[Core] Replace unsafe pickle deserialization with JSON in MSAL HTTP cache#33405
[Core] Replace unsafe pickle deserialization with JSON in MSAL HTTP cache#33405notyashhh wants to merge 1 commit into
Conversation
️✔️AzureCLI-FullTest
|
|
Hi @notyashhh, |
️✔️AzureCLI-BreakingChangeTest
|
|
Thank you for your contribution! We will review the pull request and get back to you soon. |
|
The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR. Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions). pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>
|
There was a problem hiding this comment.
Pull request overview
This PR hardens Azure CLI’s MSAL HTTP cache handling (used during az login and authenticated token acquisition) by removing unsafe pickle deserialization and writing the cache with stricter file permissions.
Changes:
- Replace
pickle.load()/pickle.dump()withjson.load()/json.dump()for the MSAL HTTP cache file. - Switch cache writes to
os.open(..., 0o600)+os.fdopen(...)to create new cache files with owner-only permissions. - Update inline comments describing expected deserialization errors.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| with open(self.filename, 'rb') as f: | ||
| return pickle.load(f) | ||
| with open(self.filename, 'r', encoding='utf-8') as f: | ||
| return json.load(f) |
| # - json.JSONDecodeError is caused by corrupted or legacy pickle cache file. | ||
| # - ValueError/KeyError from malformed JSON content. |
| # raise EOFError. This can be simulated by adding time.sleep(30) here. | ||
| # So during loading, EOFError is ignored. | ||
| pickle.dump(self.data, f) | ||
| fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600) |
Related command
az login,az account get-access-token, and any authenticatedazcommand that triggers MSAL token acquisition.Description
Replaces unsafe
pickle.load()/pickle.dump()withjson.load()/json.dump()inBinaryCache(MSAL HTTP cache at~/.azure/msal_http_cache.bin).pickle.load()can execute arbitrary code during deserialization (CWE-502). If the cache file is tampered with, it results in code execution on the nextazcommand. While default file permissions (0644) limit exploitability, pickle is unnecessary here, the cached data is simple dicts/strings (MSAL tenant discovery metadata). This was the onlyimport picklein the entiresrc/tree.Changes:
pickle→jsonfor serialization/deserializationopen()→os.open(..., 0o600)to enforce owner-only file permissions regardless of umaskBackward compatible, old pickle
.binfiles fail JSON parsing, hit the existingexcept Exceptionfallback →self.data = {}→ MSAL re-fetches tenant discovery on the next command. This is the same recovery path already used for corrupted caches.Testing Guide
Verify existing cache is gracefully discarded:
az loginaz account show# Should work normally; old pickle cache silently replaced with JSONVerify new cache is created with correct permissions:
ls -la ~/.azure/msal_http_cache.bin# Should show -rw------- (0600)Verify cache disable still works:
az config set core.use_msal_http_cache=falseaz account show# Works without cacheHistory Notes
[Core] Replace unsafe pickle deserialization with JSON in MSAL HTTP cache
This checklist is used to make sure that common guidelines for a pull request are followed.
The PR title and description has followed the guideline in Submitting Pull Requests.
I adhere to the Command Guidelines.
I adhere to the Error Handling Guidelines.